{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'{ \"a\": \"Mozilla\\\\/5.0 (Windows NT 6.1; WOW64) AppleWebKit\\\\/535.11 (KHTML, like Gecko) Chrome\\\\/17.0.963.78 Safari\\\\/535.11\", \"c\": \"US\", \"nk\": 1, \"tz\": \"America\\\\/New_York\", \"gr\": \"MA\", \"g\": \"A6qOVH\", \"h\": \"wfLQtf\", \"l\": \"orofrog\", \"al\": \"en-US,en;q=0.8\", \"hh\": \"1.usa.gov\", \"r\": \"http:\\\\/\\\\/www.facebook.com\\\\/l\\\\/7AQEFzjSi\\\\/1.usa.gov\\\\/wfLQtf\", \"u\": \"http:\\\\/\\\\/www.ncbi.nlm.nih.gov\\\\/pubmed\\\\/22415991\", \"t\": 1331923247, \"hc\": 1331822918, \"cy\": \"Danvers\", \"ll\": [ 42.576698, -70.954903 ] }\\n'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 真实世界的数据集\n",
    "# 对于每一个数据集，用各种方法，从原始数据中提取有意义的内容\n",
    "\n",
    "# the case 1 \n",
    "# the dataset USA.gov comes form the Bitly\n",
    "\n",
    "# the overview of the dataset\n",
    "\n",
    "# 2011年， URL缩短服务 Bitly 跟美国政府网站 USA.gov 合作， \n",
    "#    提供了一份从生成 .gov 或 .mil 短链接的用户那里收集来的匿名数据\n",
    "# 在 2011年， 除实时数据之外，还可以下载文本文件形式的每小时快照\n",
    "# 2017年，这项服务已经关闭， 但保存一份数据用于案例\n",
    "\n",
    "# 以每小时快照为例， 文件中各行的格式为 JSON（即 JavaScript Object Notation，常用的Web数据格式）\n",
    "# 例如， 如果只读取某个文件中的第一行， 那么所看到的结果应该是下面这样\n",
    "\n",
    "dataset_path = './../dataset/'\n",
    "\n",
    "open(dataset_path + 'bitly_usagov/example.txt').readline()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Python 有内置或者第三方模块可以将 JSON 字符串转换成 Python 字典对象\n",
    "# 用 json 模块 以及其 loads 函数 进行逐行加载数据文件\n",
    "import json\n",
    "\n",
    "path = dataset_path + 'bitly_usagov/example.txt'\n",
    "\n",
    "records = [json.loads(line) for line in open(path)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 现在 records 对象 就是一组 列组式的 Python 字典\n",
    "type(records)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.78 Safari/535.11',\n",
       " 'c': 'US',\n",
       " 'nk': 1,\n",
       " 'tz': 'America/New_York',\n",
       " 'gr': 'MA',\n",
       " 'g': 'A6qOVH',\n",
       " 'h': 'wfLQtf',\n",
       " 'l': 'orofrog',\n",
       " 'al': 'en-US,en;q=0.8',\n",
       " 'hh': '1.usa.gov',\n",
       " 'r': 'http://www.facebook.com/l/7AQEFzjSi/1.usa.gov/wfLQtf',\n",
       " 'u': 'http://www.ncbi.nlm.nih.gov/pubmed/22415991',\n",
       " 't': 1331923247,\n",
       " 'hc': 1331822918,\n",
       " 'cy': 'Danvers',\n",
       " 'll': [42.576698, -70.954903]}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "records[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'tz'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-7-e106f6eea875>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[1;31m# 假设想要知道该数据集中最常出现的是哪一个时区（即 tz 字段）\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;31m# 用列表推导式取出一组时区\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mtime_zones\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mrec\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'tz'\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mrec\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrecords\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m<ipython-input-7-e106f6eea875>\u001b[0m in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[1;31m# 假设想要知道该数据集中最常出现的是哪一个时区（即 tz 字段）\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;31m# 用列表推导式取出一组时区\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mtime_zones\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mrec\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'tz'\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mrec\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrecords\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m: 'tz'"
     ]
    }
   ],
   "source": [
    "# 用纯 Python 代码对该时区进行计数\n",
    "\n",
    "# 假设想要知道该数据集中最常出现的是哪一个时区（即 tz 字段）\n",
    "# 用列表推导式取出一组时区\n",
    "time_zones = [rec['tz'] for rec in records]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['America/New_York',\n",
       " 'America/Denver',\n",
       " 'America/New_York',\n",
       " 'America/Sao_Paulo',\n",
       " 'America/New_York',\n",
       " 'America/New_York',\n",
       " 'Europe/Warsaw',\n",
       " '',\n",
       " '',\n",
       " '']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 以上错误显示表明，并不是所有记录都有时区 tz 这个字段\n",
    "# 处理解决方法：在列表推导式末尾加上一个 if 'tz' in rec 的条件判断即可\n",
    "time_zones = [rec['tz'] for rec in records if 'tz' in rec]\n",
    "\n",
    "time_zones[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 查看前 10 个时区，发现有些是未知的（即空的）\n",
    "# 虽然可以过滤掉，但是现在先留着\n",
    "\n",
    "# 为了对时区进行计数，处理解决方法：\n",
    "#   - 只使用标准 Python 库（困难）\n",
    "#   - 使用 pandas 库（简单）\n",
    "\n",
    "# 计数的方法：遍历时区的过程中将计数值保存在字典中\n",
    "def get_counts(sequence):\n",
    "    counts = {}\n",
    "    for x in sequence:\n",
    "        if x in counts:\n",
    "            counts[x] += 1\n",
    "        else:\n",
    "            counts[x] = 1\n",
    "    return counts\n",
    "\n",
    "\n",
    "# 如果使用 Python 标准库的更高级工具，代码可以写的更简洁\n",
    "from collections import defaultdict\n",
    "\n",
    "def get_counts2(sequence):\n",
    "    counts = defaultdict(int) # values will initalize to 0\n",
    "    for x in sequence:\n",
    "        counts[x] += 1\n",
    "    return counts\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1251"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将逻辑写到函数中是为了获得更高的代码复用性\n",
    "# 要用它对时区进行处理，只需要将 time_zones 传入即可\n",
    "counts = get_counts(time_zones)\n",
    "\n",
    "counts['America/New_York']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3440"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(time_zones)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如果想要获得前 10 的时区以及其计数值\n",
    "# 这里只需要用到一些有关字典的处理技巧\n",
    "def top_counts(count_dict, n=10):\n",
    "    value_key_pairs = [(count, tz) for tz, count in count_dict.items()]\n",
    "    value_key_pairs.sort()\n",
    "    return value_key_pairs[-n:]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(33, 'America/Sao_Paulo'),\n",
       " (35, 'Europe/Madrid'),\n",
       " (36, 'Pacific/Honolulu'),\n",
       " (37, 'Asia/Tokyo'),\n",
       " (74, 'Europe/London'),\n",
       " (191, 'America/Denver'),\n",
       " (382, 'America/Los_Angeles'),\n",
       " (400, 'America/Chicago'),\n",
       " (521, ''),\n",
       " (1251, 'America/New_York')]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# and then that is :\n",
    "top_counts(counts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('America/New_York', 1251),\n",
       " ('', 521),\n",
       " ('America/Chicago', 400),\n",
       " ('America/Los_Angeles', 382),\n",
       " ('America/Denver', 191),\n",
       " ('Europe/London', 74),\n",
       " ('Asia/Tokyo', 37),\n",
       " ('Pacific/Honolulu', 36),\n",
       " ('Europe/Madrid', 35),\n",
       " ('America/Sao_Paulo', 33)]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如果搜索 Python 的标准库\n",
    "# 找到 collections.Counter 类，使得这项工作更简单\n",
    "from collections import Counter\n",
    "\n",
    "counts = Counter(time_zones)\n",
    "\n",
    "counts.most_common(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3560 entries, 0 to 3559\n",
      "Data columns (total 18 columns):\n",
      " #   Column       Non-Null Count  Dtype  \n",
      "---  ------       --------------  -----  \n",
      " 0   a            3440 non-null   object \n",
      " 1   c            2919 non-null   object \n",
      " 2   nk           3440 non-null   float64\n",
      " 3   tz           3440 non-null   object \n",
      " 4   gr           2919 non-null   object \n",
      " 5   g            3440 non-null   object \n",
      " 6   h            3440 non-null   object \n",
      " 7   l            3440 non-null   object \n",
      " 8   al           3094 non-null   object \n",
      " 9   hh           3440 non-null   object \n",
      " 10  r            3440 non-null   object \n",
      " 11  u            3440 non-null   object \n",
      " 12  t            3440 non-null   float64\n",
      " 13  hc           3440 non-null   float64\n",
      " 14  cy           2919 non-null   object \n",
      " 15  ll           2919 non-null   object \n",
      " 16  _heartbeat_  120 non-null    float64\n",
      " 17  kw           93 non-null     object \n",
      "dtypes: float64(4), object(14)\n",
      "memory usage: 500.8+ KB\n"
     ]
    }
   ],
   "source": [
    "# 用 pandas 对时区进行计数\n",
    "\n",
    "# 从原始记录的集合创建 DataFrame\n",
    "# 与将记录列表传递到 pandas.DataFrame 一样简单\n",
    "import pandas as pd\n",
    "\n",
    "frame = pd.DataFrame(records)\n",
    "\n",
    "frame.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     America/New_York\n",
       "1       America/Denver\n",
       "2     America/New_York\n",
       "3    America/Sao_Paulo\n",
       "4     America/New_York\n",
       "5     America/New_York\n",
       "6        Europe/Warsaw\n",
       "7                     \n",
       "8                     \n",
       "9                     \n",
       "Name: tz, dtype: object"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame['tz'][:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "America/New_York       1251\n",
       "                        521\n",
       "America/Chicago         400\n",
       "America/Los_Angeles     382\n",
       "America/Denver          191\n",
       "Europe/London            74\n",
       "Asia/Tokyo               37\n",
       "Pacific/Honolulu         36\n",
       "Europe/Madrid            35\n",
       "America/Sao_Paulo        33\n",
       "Name: tz, dtype: int64"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这里 frame 输出形式是摘要视图（summary view）\n",
    "# 主要用于较大的 DataFrame 对象\n",
    "# 然后就可以对 Series 使用 values_counts 方法\n",
    "\n",
    "tz_counts = frame['tz'].value_counts()\n",
    "\n",
    "tz_counts[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "America/New_York       1251\n",
       "Unknown                 521\n",
       "America/Chicago         400\n",
       "America/Los_Angeles     382\n",
       "America/Denver          191\n",
       "Missing                 120\n",
       "Europe/London            74\n",
       "Asia/Tokyo               37\n",
       "Pacific/Honolulu         36\n",
       "Europe/Madrid            35\n",
       "Name: tz, dtype: int64"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# using the library of matplorlib show the data\n",
    "# 可以用 matplotlib 可视化这个数据\n",
    "\n",
    "# 先将记录中未知或者缺失的时区值填上一个替代值\n",
    "#   - fillna 函数可以替换缺失值 NA\n",
    "#   - 而对于未知值（空字符串）则可以通过布尔型数组索引加以替换\n",
    "\n",
    "clean_tz = frame['tz'].fillna('Missing')\n",
    "\n",
    "clean_tz[clean_tz == ''] = 'Unknown'\n",
    "\n",
    "tz_counts = clean_tz.value_counts()\n",
    "\n",
    "tz_counts[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0xb78af48>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 对数据 tz 字段的缺失值处理完成\n",
    "# 使用 seaborn 包创建水平柱状图\n",
    "\n",
    "import seaborn as sns\n",
    "\n",
    "subset = tz_counts[:10]\n",
    "\n",
    "sns.barplot(y=subset.index, x=subset.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'GoogleMaps/RochesterNY'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 'a' 字段中含有执行 URL 短缩操作的浏览器、设备、应用程序的相关信息\n",
    "frame['a'][1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2'"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame['a'][50]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Mozilla/5.0 (Linux; U; Android 2.2.2; en-us; LG-P9'"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame['a'][51][:50] # long line"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0               Mozilla/5.0\n",
       "1    GoogleMaps/RochesterNY\n",
       "2               Mozilla/4.0\n",
       "3               Mozilla/5.0\n",
       "4               Mozilla/5.0\n",
       "dtype: object"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将这些 “agent” 字符串中的所有信息都解析出来是一件郁闷的工作\n",
    "# 一种策略是将这种字符串的第一节（与浏览器大致对应）分离出来并得到另外一份用户行为摘要\n",
    "\n",
    "results = pd.Series([x.split()[0] for x in frame.a.dropna()])\n",
    "\n",
    "results[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Mozilla/5.0                 2594\n",
       "Mozilla/4.0                  601\n",
       "GoogleMaps/RochesterNY       121\n",
       "Opera/9.80                    34\n",
       "TEST_INTERNET_AGENT           24\n",
       "GoogleProducer                21\n",
       "Mozilla/6.0                    5\n",
       "BlackBerry8520/5.0.0.681       4\n",
       "dtype: int64"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results.value_counts()[:8]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda\\lib\\site-packages\\ipykernel_launcher.py:10: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  # Remove the CWD from sys.path while we load stuff.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0        Windows\n",
       "1    Not Windows\n",
       "2        Windows\n",
       "3    Not Windows\n",
       "4        Windows\n",
       "Name: os, dtype: object"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 现在，假设想要按照 Windows 和 非 Windows 用户对时区统计信息进行分解\n",
    "# 简单分解：假定只要 agent 字符串中含有 'Windows' 就认定该用户为 Windows 用户\n",
    "\n",
    "# 由于有的 agent 缺失，所有首先将这些缺失的从数据中移除\n",
    "cframe = frame[frame.a.notnull()]\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "# 然后计算每行是否含有 Windows 的值\n",
    "cframe['os'] = np.where(cframe['a'].str.contains('Windows'), 'Windows', 'Not Windows')\n",
    "\n",
    "cframe['os'][:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>os</th>\n",
       "      <th>Not Windows</th>\n",
       "      <th>Windows</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>tz</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <td>245.0</td>\n",
       "      <td>276.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Africa/Cairo</th>\n",
       "      <td>0.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Africa/Casablanca</th>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Africa/Ceuta</th>\n",
       "      <td>0.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Africa/Johannesburg</th>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Africa/Lusaka</th>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/Anchorage</th>\n",
       "      <td>4.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/Argentina/Buenos_Aires</th>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/Argentina/Cordoba</th>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/Argentina/Mendoza</th>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "os                              Not Windows  Windows\n",
       "tz                                                  \n",
       "                                      245.0    276.0\n",
       "Africa/Cairo                            0.0      3.0\n",
       "Africa/Casablanca                       0.0      1.0\n",
       "Africa/Ceuta                            0.0      2.0\n",
       "Africa/Johannesburg                     0.0      1.0\n",
       "Africa/Lusaka                           0.0      1.0\n",
       "America/Anchorage                       4.0      1.0\n",
       "America/Argentina/Buenos_Aires          1.0      0.0\n",
       "America/Argentina/Cordoba               0.0      1.0\n",
       "America/Argentina/Mendoza               0.0      1.0"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 接下来，可以根据 时区 和 新得到的操作系统列表对数据进行分组\n",
    "by_tz_os = cframe.groupby(['tz', 'os'])\n",
    "\n",
    "# 分组计数，类似 value_counts 函数，可用 size 来计算\n",
    "# 并利用 unstack 对计数结果进行重塑\n",
    "\n",
    "agg_counts = by_tz_os.size().unstack().fillna(0)\n",
    "\n",
    "agg_counts[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tz\n",
       "                                  24\n",
       "Africa/Cairo                      20\n",
       "Africa/Casablanca                 21\n",
       "Africa/Ceuta                      92\n",
       "Africa/Johannesburg               87\n",
       "Africa/Lusaka                     53\n",
       "America/Anchorage                 54\n",
       "America/Argentina/Buenos_Aires    57\n",
       "America/Argentina/Cordoba         26\n",
       "America/Argentina/Mendoza         55\n",
       "dtype: int64"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最后，选取最常出现的时区\n",
    "# 为了达到这个目的，根据 agg_counts 中的行数构造一个间接索引数组\n",
    "\n",
    "# use to sort in ascending order\n",
    "indexer = agg_counts.sum(1).argsort()\n",
    "\n",
    "indexer[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>os</th>\n",
       "      <th>Not Windows</th>\n",
       "      <th>Windows</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>tz</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>America/Sao_Paulo</th>\n",
       "      <td>13.0</td>\n",
       "      <td>20.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Europe/Madrid</th>\n",
       "      <td>16.0</td>\n",
       "      <td>19.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Pacific/Honolulu</th>\n",
       "      <td>0.0</td>\n",
       "      <td>36.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Asia/Tokyo</th>\n",
       "      <td>2.0</td>\n",
       "      <td>35.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Europe/London</th>\n",
       "      <td>43.0</td>\n",
       "      <td>31.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/Denver</th>\n",
       "      <td>132.0</td>\n",
       "      <td>59.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/Los_Angeles</th>\n",
       "      <td>130.0</td>\n",
       "      <td>252.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/Chicago</th>\n",
       "      <td>115.0</td>\n",
       "      <td>285.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <td>245.0</td>\n",
       "      <td>276.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>America/New_York</th>\n",
       "      <td>339.0</td>\n",
       "      <td>912.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "os                   Not Windows  Windows\n",
       "tz                                       \n",
       "America/Sao_Paulo           13.0     20.0\n",
       "Europe/Madrid               16.0     19.0\n",
       "Pacific/Honolulu             0.0     36.0\n",
       "Asia/Tokyo                   2.0     35.0\n",
       "Europe/London               43.0     31.0\n",
       "America/Denver             132.0     59.0\n",
       "America/Los_Angeles        130.0    252.0\n",
       "America/Chicago            115.0    285.0\n",
       "                           245.0    276.0\n",
       "America/New_York           339.0    912.0"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 然后通过 take 按照这个顺序截取了最后 10 行最大值\n",
    "count_subset = agg_counts.take(indexer[-10:])\n",
    "\n",
    "count_subset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tz\n",
       "America/New_York       1251.0\n",
       "                        521.0\n",
       "America/Chicago         400.0\n",
       "America/Los_Angeles     382.0\n",
       "America/Denver          191.0\n",
       "Europe/London            74.0\n",
       "Asia/Tokyo               37.0\n",
       "Pacific/Honolulu         36.0\n",
       "Europe/Madrid            35.0\n",
       "America/Sao_Paulo        33.0\n",
       "dtype: float64"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# pandas 有一个简便方法 nlargest ，可以完成同样的工作\n",
    "agg_counts.sum(1).nlargest(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tz</th>\n",
       "      <th>os</th>\n",
       "      <th>total</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>America/Sao_Paulo</td>\n",
       "      <td>Not Windows</td>\n",
       "      <td>13.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>America/Sao_Paulo</td>\n",
       "      <td>Windows</td>\n",
       "      <td>20.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Europe/Madrid</td>\n",
       "      <td>Not Windows</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Europe/Madrid</td>\n",
       "      <td>Windows</td>\n",
       "      <td>19.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Pacific/Honolulu</td>\n",
       "      <td>Not Windows</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Pacific/Honolulu</td>\n",
       "      <td>Windows</td>\n",
       "      <td>36.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Asia/Tokyo</td>\n",
       "      <td>Not Windows</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Asia/Tokyo</td>\n",
       "      <td>Windows</td>\n",
       "      <td>35.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Europe/London</td>\n",
       "      <td>Not Windows</td>\n",
       "      <td>43.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Europe/London</td>\n",
       "      <td>Windows</td>\n",
       "      <td>31.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  tz           os  total\n",
       "0  America/Sao_Paulo  Not Windows   13.0\n",
       "1  America/Sao_Paulo      Windows   20.0\n",
       "2      Europe/Madrid  Not Windows   16.0\n",
       "3      Europe/Madrid      Windows   19.0\n",
       "4   Pacific/Honolulu  Not Windows    0.0\n",
       "5   Pacific/Honolulu      Windows   36.0\n",
       "6         Asia/Tokyo  Not Windows    2.0\n",
       "7         Asia/Tokyo      Windows   35.0\n",
       "8      Europe/London  Not Windows   43.0\n",
       "9      Europe/London      Windows   31.0"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 然后，如下代码所示，可以用柱状图进行展示\n",
    "# 传递一个额外参数到 seaborn 的 barplot 函数，绘制一个堆积条形图\n",
    "\n",
    "# rearrange the data for plotting\n",
    "count_subset = count_subset.stack()\n",
    "\n",
    "count_subset.name = 'total'\n",
    "\n",
    "count_subset = count_subset.reset_index()\n",
    "\n",
    "count_subset[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0xbaecfc8>"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAdwAAAEGCAYAAADPBiS8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3deZhV1Znv8e+PGRUQkLYRRXAgioAMpcgoihqN3sQpRuIQTAxqq0SNJhq7Fe2kTQfjQBwSgkJITDBxikElGFsZBJViFlETx+D1JjJIhKCt8N4/9io8FlXFKag6p4bf53nqYe+1117r3btK31pr7zpLEYGZmZnVribFDsDMzKwxcMI1MzMrACdcMzOzAnDCNTMzKwAnXDMzswJoVuwArO7aY489olu3bsUOw8ys3li4cOHqiOhU0TEnXKtUt27dKC0tLXYYZmb1hqS3KjvmKWUzM7MC8AjXKrVy1RoGXDV16/7C8ecWMRozs/rNI1wzM7MC8AjXzKwe+Pjjj1m1ahUffvhhsUMxoFWrVuy99940b94873OccM3M6oFVq1bRpk0bunXrhqRih9OoRQRr1qxh1apVdO/ePe/zPKVsZlYPfPjhh3Ts2NHJtg6QRMeOHas92+CEa2ZWTzjZ1h078r2oMwlX0imSQtJBtdR+iaQJO3H+KEnXStpT0nRJSyW9JOnxGo5zs6Qlkl6U9DtJu+xgO+MkXVmTsZmZ2Y6rMwkXGAXMBc6s6YYlNYuI0ogYuxPNHA/MAG4EnoyIQyOiJ3B1jQT5qU0R0TciegH/C1xYw+2bmVkR1ImEK2k3YAjwDVLClTRC0ixJv5X0qqQfSjpL0guSlkvaP9XrJOlBSQvS15BUPk7SREkzgampvell/UmanNpZJum0VH63pFJJKyTdkBOfgL7AIqAzsKrsWEQsy2nzKUmLUrtfyjn/ijRifVHSZdW4NXOAA1Ibj0hamGIbk9P2hpzt0yVNqeD+9pX0XLrWhyW1r6xDSWPSPSht/+E7PNxm/Navt2/svfXLzMyqp04kXOBkYEZEvAqsldQ/lR8KfAvoDZwD9IiIw4FJwKWpzu3ArRFxGHBaOlZmAPCliPhquf7+A1gfEb0jog/wP6n82ogoAfoAR0rqk8r7AUsjIoA7gXskPZ2mmPdKdT4ETomI/sBRwI+VGQCcBwwEjgC+Kanf9m6IpGbACcDyVPT1iBgAlABjJXXcXhs5pgLfTde6HLi+sooRMTEiSiKipMOuTavRhZlZxW655RZ69epFr169uO2229i4cSMnnngihx56KL169eL+++8vdogFUVf+LGgUcFvanpb2HwMWRMS7AJJeA2amOsvJkhrAMUDPnAfYbSW1SduPRsSmCvo7hpyp64hYlzbPSKPHZmQj2Z7AMrLp5CdS3T9K2i+VnQAsltQLeB/4L0nDgS1AF2BPYCjwcERsTNfxEDAMWFzJvWgtaUnangPck7bHSjolbe8DHAisqaSNrSS1A3aPiFmp6BfA77Z3nplZTVi4cCGTJ0/m+eefJyIYOHAgmzdvZq+99uKxxx4DYP369UWOsjCKnnDTSO1ooJekAJoCATwOfJRTdUvO/hY+jb0JMKh8Yk0JeGNl3aY+cut3B64EDouIdWlqtlU6fBzZ6BmAiFgL/Br4dZqmHg60AToBAyLiY0lvpvOr+yrbpojoWy62EWS/JAyKiH9KeiYnttzraIWZWR0yd+5cTjnlFHbddVcATj31VJo3b86f/vQnvvvd73LSSScxbNiwIkdZGHVhSvl0YGpE7BsR3SJiH+ANspFhPmYCl5TtSOpbRd3KzmkPtCVL0Osl7Uk2ei0bITaLiDVp/+iyN4fTSHp/4G2gHfD3lGyPAvZNzc8GTpa0i6RdgVPIRq7V0Q5Yl5LtQWRT02X+JulgSU1S258REeuBdZLKfqLPAWaVr2dmVhuyJ3HbWrhwIb179+aaa67hxhtvLHBUxVEXEu4o4OFyZQ8C5Z+7VmYsUJJeCHqJ/N7q/T7QPr3EtBQ4KiKWkk3zrgDuBZ5NdY8F/pRz7gCgVNIyYD4wKSIWAPelOEqBs4CXASJiETAFeAF4PtWvbDq5MjOAZqnP/wSeyzl2NTCd7Dn0u5Wc/zVgfDq/L9mb1mZmtW748OE88sgj/POf/2Tjxo08/PDDDBgwgF122YWzzz6bK6+8kkWLFhU7zIJQZb99WEbSJLIk+dx2Kzcwfbq0jukXHFDhsa7XLa+w3Mxqx8qVKzn44IOLHcYOueWWW7j33nsBOP/88zn44IO56qqraNKkCc2bN+fuu++mpKSkyFFWX0XfE0kL08u32yj6M9y6LiLOL3YMZmb12RVXXMEVV1zxmbLPf/7zRYqmeJxwiyC9KPZUBYdGlj0rNjOzhsUJtwhSUs3n5a6iatH5ELpeV1rsMMzMGoS68NKUmZlZg+eEa2ZmVgBOuGZmZgXgZ7hWqZWr1jDgqqmfKVs4/twiRWNmVr854ZqZ1UPlfxneWfn8Mi2JK664gh//+McA3HzzzWzYsIFx48ZVes4jjzxCjx496Nmz52fK33//ffbff39Wr16NJObPn8/gwYP561//yt5778369evp3r07q1evZty4cQwfPpxjjjkm7+vp1q0bpaWl7LHHHnmfU9s8pWxmZnlp2bIlDz30EKtXr877nEceeYSXXnppm/Ldd9+df/3Xf2XlypUAzJs3j379+jFv3jwAnnvuOQYOHEiTJk248cYbq5Vs6yonXDMzy0uzZs0YM2YMt9566zbH3nrrLUaOHEmfPn0YOXIkb7/9NvPmzePRRx/lqquuom/fvrz22mufOWfIkCFbE+y8efO4/PLLP7M/ePBgAEaPHs0DDzwAZCPX66+/nv79+9O7d29efvllANasWcNxxx1Hv379uOCCCz7zGc7llwcE+NGPfsSECRMAuPzyyzn66KMBeOqppzj77LPZvHkzo0ePplevXvTu3bvCa64uJ1wzM8vbxRdfzH333bfNknqXXHIJ5557LsuWLeOss85i7NixDB48mC9+8YuMHz+eJUuWsP/++3/mnMGDB29NsK+//jpf/vKXKS3N/vZ/3rx5DBkypMIY9thjDxYtWsRFF13EzTffDMANN9zA0KFDWbx4MV/84hd5++23gc8uD/jcc8/x85//nMWLFzN8+HDmzMnWkSktLWXDhg18/PHHzJ07l2HDhrFkyRLeeecdXnzxRZYvX85555230/fOCdfMzPLWtm1bzj333K2jwzLz58/nq1/N1pw555xzmDt37nbbKhvhvvHGG3Tr1o1WrVoREWzYsIGFCxdy+OGHV3jeqaeeCsCAAQN48803AZg9ezZnn302ACeeeCLt27cHPrs84G677capp57KnDlzGDBgAAsXLuSDDz6gZcuWDBo0iNLSUubMmcOwYcPYb7/9eP3117n00kuZMWMGbdu23aH7lavBJ1xJmyUtyfm6usjxXCPpLEnjJIWkA3KOXZ7K8v4Ub0kj0pq8FR0rkTShkmNvSqo7bxOYWb1x2WWXcc8997BxY2VLjm9dk7xKBx54IOvWreMPf/gDgwYNArIkOnnyZLp3785uu+1W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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.barplot(x='total', y='tz', hue='os', data=count_subset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0xbd5fc88>"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAdwAAAEHCAYAAAAEWvcZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3deZRV1Zn38e+PGRUQ1E4jihCVKBbIUA6AIAoaTWzj1EbiEDQGtVWiRN9omyiapM0rJiqJQxCFkGg0jiGoRGNUQEAt5klNEDX4ujqCSIuirfC8f5xdeC1ruAVV91YVv89atTzDPns/+xbL5+59Tp2tiMDMzMzqV7NiB2BmZrY9cMI1MzMrACdcMzOzAnDCNTMzKwAnXDMzswJoUewArOHaddddo1u3bsUOw8ys0Zg3b96aiNitsnNOuFalbt26UVZWVuwwzMwaDUlvVHXOU8pmZmYF4BGuVWnF6rX0v3xKscOwApo37qxih2DWZHmEa2ZmVgAe4ZqZNQKffPIJq1ev5qOPPip2KAa0adOGPfbYg5YtW+Z9jROumVkjsHr1atq1a0e3bt2QVOxwtmsRwdq1a1m9ejXdu3fP+zpPKZuZNQIfffQRu+yyi5NtAyCJXXbZpdazDU64ZmaNhJNtw7E1v4sGk3AlnSgpJO1XT/WXShq/DdePkHSVpC9JmiZpkaTlkh6v4zg3SVooaamkByTtsJX1jJV0WV3GZmZmW6/BJFxgBDALOK2uK5bUIiLKImL0NlRzDDAduA54KiIOjIiewBV1EuRnNkZEn4goAf4XOL+O6zczsyJoEA9NSdoJGAQcAUwFxkoaClwL/DfQB3gYWAJ8D2gLnBARKyXtBtwBdE3VXRIRz0saC+wOdAPWSJoAXBYRx6X2fgmUAgFcGxEPSbodOCjV/2BEXJPiU4phPtAZeLI89ohYnNOHPwIdgZbADyPij+ncGOCcdMnEiLg5z49mJtA71fEosCfQBrglIiak4xsiYqe0fQpwXESMrPD59kmf0Q7ASuCciFhXWYOSRgGjALp0aMkj7cblGao1BW9e5993rq5XLyl2CNaENJQR7gnA9Ih4FXhXUr90/ECyBNsLOBPoEREHAxOBi1OZW4CbIuIg4OR0rlx/4BsR8a0K7f0IWB8RvSKiN/DXdPyqiCglS3KHS+qdjvcFFkVEALcCd0l6Jk0x757KfAScGBH9yL44/FyZ/sDZwCHAocB3JfWt6QOR1AI4luxLBmRJsj/Zl4TRknapqY4cU4AfpL4uAa6pqmBETIiI0ogo7bRj81o0YWZWuV/84heUlJRQUlLCzTffzAcffMDXv/51DjzwQEpKSrj//vuLHWJBNIgRLtl0cvmo7760/xjwUkS8DSBpJZ+NLJeQJTWA4UDPnBvY7SW1S9tTI2JjJe0NJ2fqOme0d2oa4bUgG8n2BBaTTSc/kcr+WdKX07FjgQWSSoD3gP+SNATYDHQBvgQcBjwSER+kfjwMDAYWVPFZtJW0MG3PBO5K26MlnZi29wT2BdZWUccWkjoAO0fEc+nQb4AHarrOzKwuzJs3j0mTJvHCCy8QERxyyCFs2rSJ3XffncceewyA9evXFznKwih6wk0jtSOBEkkBNCeb5n0c+Din6Oac/c18FnszYEDFxJoS8AdVNZvayC3fHbgMOCgi1kmaTDZ9C3A02egZgIh4F7gXuFfSNGAI0A7YDegfEZ9Iej1dX9tH2TZGRJ8KsQ0l+5IwICI+lPRsTmy5/WiDmVkDMmvWLE488UR23HFHAE466SRatmzJX/7yF37wgx9w3HHHMXjw4CJHWRgNYUr5FGBKROwVEd0iYk9gFdnIMB9PAheV76T7lbW9piPQnixBr5f0JbLRa/kIsUVErE37R5Y/OZxG0nsDbwIdgH+mZHsEsFeqfgZwgqQdJO0InEg2cq2NDsC6lGz3I5uaLvffkvaX1CzV/TkRsR5YJ6n8X/SZwHMVy5mZ1YfsTtwXzZs3j169enHllVdy3XXXFTiq4mgICXcE8EiFYw8BFe+7VmU0UCppsaTl5PdU70+AjulPbxYBR0TEIrJp3mXA3cDzqexRwF9yru0PlElaDMwhewjqJeCeFEcZcDrwMkBEzAcmAy8CL6TyVU0nV2U60CK1+WNgbs65K4BpZPeh367i+m8D49L1fcietDYzq3dDhgzh0Ucf5cMPP+SDDz7gkUceoX///uywww6cccYZXHbZZcyfP7/YYRaEqvr2YRlJE8mS5NwaCzcxvbu0jWnn7VPsMMyKpiE9pbxixQr233//YoexVX7xi19w9913A3Duueey//77c/nll9OsWTNatmzJ7bffTmlpaZGjrL3KfieS5qWHb7+g6PdwG7qIOLfYMZiZNWZjxoxhzJgxnzv21a9+tUjRFI8TbhGkB8WeruTUsPJ7xWZm1rQ44RZBSqr5PNxVVK06H0DXq8uKHYaZWZPQEB6aMjMza/KccM3MzArACdfMzKwAfA/XqrRi9Vr6Xz6l2GFYIzZv3FnFDsGswXDCNTNrhOr6y3A+X44kMWbMGH7+858DcOONN7JhwwbGjh1b5TWPPvooPXr0oGfPnp87/t5777H33nuzZs0aJDFnzhwGDhzIP/7xD/bYYw/Wr19P9+7dWbNmDWPHjmXIkCEMHz487/5069aNsrIydt1117yvqW+eUjYzs7y0bt2ahx9+mDVr1uR9zaOPPsry5cu/cHznnXfmX//1X1mxYgUAs2fPpm/fvsyePRuAuXPncsghh9CsWTOuu+66WiXbhsoJ18zM8tKiRQtGjRrFTTfd9IVzb7zxBsOGDaN3794MGzaMN998k9mzZzN16lQuv/xy+vTpw8qVKz93zaBBg7Yk2NmzZ3PppZd+bn/gwIEAjBw5kgcffBDIRq7XXHMN/fr1o1evXrz88ssArF27lqOPPpq+ffty3nnnfe4dzhWXBwS44YYbGD9+PACXXnopRx55JABPP/00Z5xxBps2bWLkyJGUlJTQq1evSvtcW064ZmaWtwsvvJB77rnnC0vqXXTRRZx11lksXryY008/ndGjRzNw4ECOP/54xo0bx8KFC9l7770/d83AgQO3JNjXXnuNf//3f6esLPvb/9mzZzNo0KBKY9h1112ZP38+F1xwATfeeCMA1157LYcddhgLFizg+OOP58033wQ+vzzg3LlzufPOO1mwYAFDhgxh5sxsHZmysjI2bNjAJ598wqxZsxg8eDALFy7krbfeYunSpSxZsoSzzz57mz87J1wzM8tb+/btOeuss7aMDsvNmTOHb30rW3PmzDPPZNasWTXWVT7CXbVqFd26daNNmzZEBBs2bGDevHkcfPDBlV530kknAdC/f39ef/11AGbMmMEZZ5wBwNe//nU6duwIfH55wJ122omTTjqJmTNn0r9/f+bNm8f7779P69atGTBgAGVlZcycOZPBgwfz5S9/mddee42LL76Y6dOn0759+636vHI1+YQraZOkhTk/VxQ5nislnS5prKSQtE/OuUvTsbzf4i1paFqTt7JzpZLGV3HudUkN52kCM2s0LrnkEu666y4++KCqJce3rElerX333Zd1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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 以上这张图不容易展现出 Windows 用户在小分组中的相对比例，因此标准化分组百分比之和为 1\n",
    "\n",
    "def norm_total(group):\n",
    "    group['normed_total'] = group.total / group.total.sum()\n",
    "    return group\n",
    "\n",
    "results = count_subset.groupby('tz').apply(norm_total)\n",
    "\n",
    "# 处理后再次绘制图形\n",
    "sns.barplot(x='normed_total', y='tz', hue='os', data=results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    0.393939\n",
       "1    0.606061\n",
       "2    0.457143\n",
       "3    0.542857\n",
       "4    0.000000\n",
       "Name: total, dtype: float64"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 还可以使用 groupby 的 transform 方法，更高效的计算标椎化的和 \n",
    "g = count_subset.groupby('tz')\n",
    "\n",
    "results2 = count_subset.total / g.total.transform('sum')\n",
    "\n",
    "results2[:5]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
